/* gchars.c */

#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "DeskLib:Error.h"
#include "DeskLib:File.h"

#include "gchars.h"
#include "graphics.h"
#include "key.h"
#include "scrn.h"

extern graphic *graphics_pool;

/* Number of pixels between two rows of chars (including chars) */
#define SPACING 20

/* Graphic data for chars */
graphic *gchars_pool;

/* Cursor position */
int gchars_x,gchars_y;

void gchars_init(char *filename)
{
  gchars_pool = malloc(File_Size(filename));
  /* It's only a game, I can't be bothered to check for memory shortage */
  Error_CheckFatal(File_LoadTo(filename,gchars_pool,NULL));
  gchars_x = gchars_y = 0;
}

void gchars_moveto(int x,int y)
{
  gchars_x = x;
  gchars_y = y;
}

void gchars_writec(char ch)
{
  ch = toupper(ch);
  switch (ch)
  {
    case ' ':
      ch = 255;
      break;
    case 13:
    case 10:
      gchars_x = 0;
      gchars_y += SPACING;
      return;
    case '.':
      ch = gchars_STOP;
      break;
    case '-':
      ch = gchars_DASH;
      break;
    case '?':
      ch = gchars_QUEST;
      break;
    case '!':
      ch = gchars_PLING;
      break;
    case '\'':
      ch = gchars_APOST;
      break;
    case ':':
      ch = gchars_COLON;
      break;
    case ',':
      ch = gchars_COMMA;
      break;
    default:
      if (ch >= '0' && ch <= '9')
        ch += gchars_NUM - '0';
      else if (ch >= 'A' && ch <= 'Z')
        ch += gchars_ALPHA - 'A';
      else
        return;
      break;
  }
  if (gchars_x >= 320)
  {
    gchars_x = 0;
    gchars_y += SPACING;
  }
  if (ch == 255)
    (*scrn_fast_plotter)(graphics_pool,gchars_x,gchars_y,scrn_offset);
  else
    (*scrn_fast_plotter)(&gchars_pool[ch],gchars_x,gchars_y,scrn_offset);
  gchars_x += 16;
}

void gchars_writes(char *str)
{
  while (*str)
    gchars_writec(*(str++));
}

void gchars_printf(char *format,...)
{
  va_list ptr;
  char string[256];

  va_start(ptr,format);
  vsprintf(string,format,ptr);
  gchars_writes(string);
  va_end(ptr);
}

void gchars_centre(char *str)
{
  char firstline[21];

  if (strlen(str) > 20)
  {
    char *rchr;

    strncpy(firstline,str,20);
    firstline[20] = 0;
    rchr = strrchr(firstline,' ');
    if (!rchr)
      rchr = firstline + 20;
    *rchr = 0;
    gchars_centre(firstline);
    gchars_writec('\n');
    rchr = str + (int) rchr - (int) firstline;
    while (*rchr == ' ') rchr++;
    gchars_centre(rchr);
  }
  else
  {
    gchars_x = (160 - 8 * strlen(str)) & ~3;
    gchars_writes(str);
  }
}

void gchars_centref(char *format,...)
{
  va_list ptr;
  char string[256];

  va_start(ptr,format);
  vsprintf(string,format,ptr);
  gchars_centre(string);
  va_end(ptr);
}

void gchars_input(char *buffer,int len,char *valid)
{
  int i;
  char ch;

  i = 0;
  key_flush_buffer();
  gchars_writec('-');
  gchars_x -= 16;
  do
  {
    ch = toupper(key_inkey());
    if ((ch == 127 || ch == 8) && i > 0)
    {
      gchars_x -= 16;
      gchars_writes("- ");
      gchars_x -= 32;
      buffer[i] = 0;
      i--;
    }
    else if (ch == 13)
    {
      buffer[i] = 0;
      gchars_writec(' ');
    }
    else if (i < len && strchr(valid,ch))
    {
      gchars_writec(ch);
      gchars_writec('-');
      gchars_x -= 16;
      buffer[i] = ch;
      i++;
    }
  }
  while (ch != 13);
}
